<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box {
        width: 200px;
        border: 1px solid green;
      }
      .float-box {
        float: left;
        width: 100px;
        height: 100px;
        background-color: gray;
      }
      /* 增加以下代码来解决环绕问题 */
      .box > p {
        overflow: hidden;
      }

      /* 图片留白解决方案 */
      img {
        display: block;
      }

      /* tab切换 */
      .tab {
        width: 500px;
        margin: 50px auto 20px;
      }
      .tab .header {
        overflow: hidden;
      }
      .tab .header div {
        float: left;
        width: 25%;
        padding: 5px;
        box-sizing: border-box;
        text-align: center;
      }

      .tab .header .active {
        background-color: skyblue;
      }

      .content {
        height: 200px;
        border: 1px solid red;
      }

      .content div {
        display: none;
      }

      .content .active {
        display: block;
      }

      /* JS实现发帖功能 */
      .blob {
        width: 400px;
        margin: 0 auto;
        border: 1px dashed #6c7d8e;
      }
      .blob .display-area a {
        float: right;
        text-decoration: none;
      }
      .blob .display-area ul {
        padding-right: 15px;
      }

      /* 事件委托 */
      .delegate {
        width: 200px;
        margin: 10px auto;
      }
      /* 事件委托 */

      /* 图片跟随移动 */
      .mouse-flover {
        position: absolute;
        top: 0;
        left: 0;
      }

      /* 实现鼠标拖拽元素 */
      .drag-move {
        width: 200px;
        height: 200px;
        background-color: green;
        border: 1px solid #d34349;
        margin: 10px auto;
        position: absolute;
        top: 0;
        left: 500px;
        z-index: 99;
      }
      /* 实现鼠标拖拽元素 */
    </style>
  </head>
  <body>
    <div class="box">
      <div class="float-box"></div>
      <p>
        这是文字文字这是文字文字这是文字文字这是文字文字这是文字文字这是文字文字这是文字文字这是文字文字这是文字文字这是文字文字这是文字文字这是文字文字这是文字文字
      </p>
    </div>

    <!-- 图片留白问题 -->
    <div class="blank-box">
      <img src="图片地址" alt="" />
    </div>

    <!-- IE条件HACK写法 -->
    <!-- [IF IE]>
        <p style="color:red">只能被IE识别</p>
    <![END IF]-->

    <!-- JS实现tab栏切换 -->
    <div class="tab">
      <div class="header">
        <div class="active">tab1</div>
        <div>tab2</div>
        <div>tab3</div>
        <div>tab4</div>
      </div>
      <div class="content">
        <div class="active">content1</div>
        <div>content2</div>
        <div>content3</div>
        <div>content4</div>
      </div>
    </div>
    <!-- JS实现tab栏切换 -->

    <!-- JS实现发帖删帖功能 -->
    <div class="blob">
      <h3>JS实现发帖删帖功能</h3>
      <div class="input-area">
        <input type="text" name="" placeholder="写点什么？" />
        <button>添加评论</button>
      </div>
      <div class="display-area">
        <ul></ul>
      </div>
    </div>
    <!-- JS实现发帖删帖功能 -->

    <!-- 事件委托 -->
    <div class="delegate">
      <h3>JS实现事件委托</h3>
      <div class="input-area">
        <input type="text" name="" placeholder="写点什么？" />
        <button>添加评论</button>
      </div>
      <ul></ul>
    </div>
    <!-- 事件委托 -->

    <!-- 鼠标移动，图片跟着移动 -->
    <img
      src="https://static.veer.com/veer/static/resources/keyword/2020-02-19/b94a42fb11d64052ae5a9baa25f5370c.jpg"
      class="mouse-flover"
      alt="向日葵"
      width="50"
    />
    <!-- 鼠标移动，图片跟着移动 -->

    <!-- 实现鼠标拖拽元素 -->
    <div class="drag-move">
      这是不可被选中的文字这是不可被选中的文字这是不可被选中的文字这是不可被选中的文字这是不可被选中的文字
    </div>
    <!-- 实现鼠标拖拽元素 -->
    <script>
      /***数组常用API***/
      var arr = [1, 2, 4];
      console.log(arr.indexOf(1));
      console.log(arr.indexOf(123));

      arr.forEach((item) => {
        item++;
      });

      console.log("item", arr);

      arr.filter(function (item) {
        return item > 2;
      });

      arr.map((item, index, arr) => {
        return item++;
      });

      var res = arr.some((item, index, arr) => {
        return item > 1;
      });
      console.log("res", res); //==>2

      var succ = arr.every((item, index, arr) => {
        return item > 2;
      });
      console.log("succ", succ); //===false

      var reduc = arr.reduce((prev, current, index, arr) => {
        //prev第一次是数组的第一个元素，以后都是上一次循环的返回值
        //current是当前的值
        return prev + current;
      });
      /***数组常用API***/

      /**** JS 实现TAB切换 ****/
      var headers = document.querySelectorAll(".header div");
      var content = document.querySelectorAll(".content div");

      // 为头部绑定单击事件
      headers.forEach((item, index) => {
        item.onclick = function () {
          // 将其所有元素的样式置空
          content.forEach((contentItem, contentIndex) => {
            contentItem.className = "";
            headers[contentIndex].className = "";
          });
          //用来记住索引
          item.index = index;
          // 把点选的设置为active
          this.className = "active";
          content[item.index].className = "active";
        };
      });
      console.log(headers);
      /**** JS 实现TAB切换 ****/

      /****** JS 实现发帖删除******/
      //获得关键元素
      var tput = document.querySelector(".blob input");
      var btn = document.querySelector(".blob button");
      var ul = document.querySelector(".blob .display-area ul");

      // 获取元素，添加元素
      btn.onclick = () => {
        var li = document.createElement("li");
        li.innerHTML = tput.value + "<a>删除</a>";

        var a = li.querySelector("a");
        a.addEventListener("click", () => {
          li.remove();
        });

        ul.insertBefore(li, ul.children[0]);
      };
      /****** JS 实现发帖删除******/

      /*****事件委托*****/
      var fa = document.querySelector(".delegate ul");
      var delegateIput = document.querySelector(".delegate input");
      var delegateBtn = document.querySelector(".delegate button");

      delegateBtn.onclick = function () {
        var li = document.createElement("li");
        li.innerText = delegateIput.value;
        fa.insertBefore(li, fa.children[0]);
      };

      // 给父亲绑定事件
      fa.addEventListener("click", (event) => {
        alert(event.target.innerText);
      });
      /*****事件委托*****/

      /***图片跟随效果****/
      // var oimg = document.querySelector(".mouse-flover");
      // document.addEventListener("mousemove", function (e) {
      //   var e = e || event;
      //   //此时，鼠标在图片的左上角
      //   oimg.style.left = e.pageX;
      //   oimg.style.top = e.pageY;

      //   //所以，要减去图片的宽度
      //   oimg.style.left = e.pageX - oimg.width / 2 + 'px';
      //   oimg.style.top = e.pageY - oimg.height / 2 + 'px';
      // });
      /***图片跟随效果****/

      /**********鼠标拖拽实现*********/
      var dragDiv = document.querySelector(".drag-move");
      //这里设置边界值，就是不让DIV拖到窗口之外
      var dictMaxX = window.innerWidth - dragDiv.offsetWidth;
      var dictMaxY = window.innerHeight - dragDiv.offsetHeight;
      //绑定按下监听
      dragDiv.onmousedown = function (e) {
        console.log(e);
        //元素的left、top实际上就是page属性，减去offset属性，即可
        //获取这个div的offsetX和offsetY，当然也可以用移动中的offset，但是这个点击时获取，可能相对准确一点
        var offsetX = e.offsetX;
        var offsetY = e.offsetY;

        //在这里禁止文字的选择
        // document.getSelection?document.getSelection().removeAllRanges():document.selection().remove();

        //绑定鼠标移动的监听事件
        document.onmousemove = function (e) {
          var dictX = e.pageX - offsetX;
          var dictY = e.pageY - offsetY;

          console.log("before dictX", dictX);
          console.log("before dictY", dictY);
          //边界值判断
          if (dictX < 0) {
            dictX = 0;
          }
          if (dictX > dictMaxX) {
            dictX = dictMaxX;
          }
          if (dictY < 0) {
            dictY = 0;
          }
          if (dictY > dictMaxY) {
            dictY = dictMaxY;
          }

          console.log("after dictX", dictX);
          console.log("after dictY", dictY);

          dragDiv.style.top = dictY + "px";
          dragDiv.style.left = dictX + "px";
        };
        //鼠标弹起，解除绑定
        dragDiv.onmouseup = function () {
          document.onmousemove = null;
        };
      };
      /**********鼠标拖拽实现*********/

      /************模拟call方法的实现**************/
      Function.prototype.callSelf = function (context, ...args) {
        // 要做两件事，1、改变this指向、2、调用函数
        //兼容没传值的情况
        context = !!context ? Object(context) : window;
        //这里的this指向的就是调用的对象，其实就是调用的函数本身
        context.fun = this;
        //调用函数
        const ret = context.fun(...args);
        //删除属性
        delete context.fun;

        return ret;
      };

      function test(a, b, c) {
        console.log(a, b, c);
      }
      const obj = { a: 1 };
      //调用函数
      test.callSelf(obj, 1, 2, 3);
      /************模拟call方法的实现**************/

      /************模拟bind方法的实现**************/
      // Bind的实现
      Function.prototype.bindSelf = function (context, ...args) {
        //返回的是一个函数
        const that = this;
        return function () {
          return that.call(context, ...args);
        };
      };
      /************模拟bind方法的实现**************/

      /************ES6 类***********/
      class Student {
        //此处定义的属性，会定义在实例上。相当于构造函数中this.course = 'chinese';
        course = "chinese";
        //构造函数，new的时候自动执行
        constructor(name, age) {
          this.name = name;
          this.age = age;
          this.hobby = ["basketball"];
        }
        // 方法，定义在原型上
        study() {
          console.log("study hard...");
        }
        // 为属性提供get、set方法
        set hobby(hobby) {
          this.hobby.push(hobby);
        }
        get hobby() {
          return this.hobby;
        }
        // 静态方法
        static eat() {
          console.log("eat sth...");
        }
      }
      let s1 = new Student("zs", 23);
      console.log(s1.name);
      s1.hobby = "football";
      console.log(s1.hobby);
      Student.eat();
      /************ES6 类***********/

      /************ES6 类模拟***********/
      var Student = (function () {
        function Student(name) {
          // 限制只能new
          if (!(this instanceof Student)) {
            throw new Error("class can only be new");
          }
          this.name = name;
        }
        return Student;
      })();
      Student("zs"); //===>class can only be new
      /************ES6 类模拟***********/

      /************ES6 类继承***********/
      class Person {
        constructor(name) {
          this.name = name;
        }
        eat() {
          console.log("eating ....");
        }
      }

      class Professor extends Person {
        constructor(name, age) {
          super(name);
          this.age = age;
        }
        eat() {
          console.log("wash hand");
          super.eat();
        }
      }
      let pro = new Professor("zx", 23);
      console.log(pro.eat());
      /************ES6 类继承***********/

      /************ES6 Promise***********/
      //Promise new 的时候，传入一个立即执行函数
      const promise = new Promise((resove,reject)=>{
        console.log(123);

        //状态改变为成功状态
        // resolve();
        // 状态改变为失败状态
        // reject();
        // 如果既不写resolve，又不写reject，则默认是等待态,那then里的函数，都不会执行
      });
      // 每一个new的Promise都有then方法，接受两个函数，一个成功回调，一个失败回调
      promise.then((succ)=>{
        // 成功回调
        console.log('succ',succ);
      },(fail)=>{
        // 失败回调
        console.log('fail',fail);
      });
      /************ES6 Promise***********/
    </script>
  </body>
</html>
